﻿using System;
using System.Net;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Threading;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using Microsoft.Phone.Controls;


namespace JHMVVMFramework.ViewModel
{
    public abstract class BaseViewModel : INotifyPropertyChanged, INotifyPropertyChanging, INotifyDataErrorInfo
    {

        private Dispatcher _dispatcher;
        public BaseViewModel()
        {

            _dispatcher = Deployment.Current.Dispatcher;

        }

        protected Dispatcher Dispatcher { get { return _dispatcher; } }
        protected PhoneApplicationFrame PhoneApplicationFrame { get { return (Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame); } }

        private Dictionary<String, List<String>> m_errors =
           new Dictionary<string, List<string>>();

        public event PropertyChangedEventHandler PropertyChanged;

        public event PropertyChangingEventHandler PropertyChanging;

        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

        public System.Collections.IEnumerable GetErrors(string propertyName)
        {
            if (String.IsNullOrEmpty(propertyName) ||
                !m_errors.ContainsKey(propertyName)) return null;
            return m_errors[propertyName];
        }

        public bool HasErrors
        {
            get { return m_errors.Count > 0; }
        }

        protected bool SetProperty<T>(ref T storage, T value, string propertyName)
        {
            if (object.Equals(storage, value)) return false;
            this.FirePropertyChanging(new PropertyChangingEventArgs(propertyName));
            storage = value;
            this.FirePropertyChanged(new PropertyChangedEventArgs(propertyName));
            return true;
        }

        protected virtual void FirePropertyChanging(PropertyChangingEventArgs args)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, args);
            }
        }

        protected virtual void FirePropertyChanged(PropertyChangedEventArgs args)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, args);
            }

        }

        protected virtual void FireErrorsChanged(DataErrorsChangedEventArgs args)
        {
            if (ErrorsChanged != null)
                ErrorsChanged(this, args);
        }

        protected virtual void AddError(string propertyName, string error, bool isWarning)
        {
            if (!m_errors.ContainsKey(propertyName))
                m_errors[propertyName] = new List<string>();

            if (!m_errors[propertyName].Contains(error))
            {
                if (isWarning) m_errors[propertyName].Add(error);
                else m_errors[propertyName].Insert(0, error);
                FireErrorsChanged(new DataErrorsChangedEventArgs(propertyName));
            }
        }

        protected virtual void RemoveError(string propertyName, string error)
        {
            if (m_errors.ContainsKey(propertyName) &&
                m_errors[propertyName].Contains(error))
            {
                m_errors[propertyName].Remove(error);
                if (m_errors[propertyName].Count == 0) m_errors.Remove(propertyName);
                FireErrorsChanged(new DataErrorsChangedEventArgs(propertyName));
            }
        }
    }
}

